package ru.mirent;

import io.qameta.allure.Allure;
import net.sourceforge.plantuml.FileFormat;
import net.sourceforge.plantuml.FileFormatOption;
import net.sourceforge.plantuml.SourceStringReader;
import net.sourceforge.plantuml.core.DiagramDescription;
import ru.mirent.entity.TypeDiagram;

import java.io.*;
import java.nio.charset.StandardCharsets;

import static java.util.Objects.isNull;

/**
 * Класс генерации и созхранения диаграмм в формате: svg.
 */
public class SvgTypeDiagram extends TypeDiagram {

    public SvgTypeDiagram(String sourceCodeDiagram) {
        super(sourceCodeDiagram);
    }

    /**
     * Получить svg-код сгенерированного изображения в виде xml-кода.
     * @return {@link String} xml-код в виде текста
     */
    public String svgCode() {
        String result;

        try {
            SourceStringReader reader = new SourceStringReader(getSourceCodeDiagram());
            ByteArrayOutputStream os = new ByteArrayOutputStream();

            DiagramDescription desc = reader.outputImage(os, new FileFormatOption(FileFormat.SVG));

            if (isNull(desc)) {
                throw new RuntimeException("Ошибка генерации диаграммы");
            }

            result = os.toString(StandardCharsets.UTF_8);
            os.close();
        } catch (IOException ex) {
            throw new RuntimeException(ex.getCause());
        }

        return result;
    }

    /**
     * Прикрепить диаграмму к Allure-отчету.
     * @param attachmentName имя вложения
     */
    public void attachDiagramToAllure(String attachmentName) {
        Allure.addAttachment(attachmentName, "image/svg+xml", svgCode(), "svg");
    }

    /**
     * Сохранить диаграмму в файле.
     * @param file путь к файлу для сохранения
     */
    public void saveToFile(File file) {
        try {
            String svgCode = svgCode();

            BufferedWriter writer = new BufferedWriter(new FileWriter(file));

            writer.write(svgCode);
            writer.close();
        } catch (IOException ex) {
            // TODO Сделать корректную обработку ошибки
            throw new RuntimeException(ex.getCause());
        }
    }
}
